#include "Lexico.h"

int Lexico::codigoArchivo = 0;
int Lexico::codigoArchivoNivel1 = 0;

using namespace std;

// CONSTRUCTOR
Lexico::Lexico(char * modo, int nivel, bool parcial) {
	
	string nombre_archivo;
	stringstream cod_str;
			
	nombre_archivo = Entorno::Instance().getDataPath();
	nombre_archivo += NOMBRE_ARCHIVO_LEXICO;
	
	destroy = false;
	
	if (parcial) {		
		if (nivel == 0) {
			Lexico::codigoArchivo++;
			nombre_archivo += "_N0_";
			cod_str << codigoArchivo;
		} else {
			Lexico::codigoArchivoNivel1++;
			nombre_archivo += "_N1_";
			cod_str << codigoArchivoNivel1;
		}
		nombre_archivo += cod_str.str();
		nombre_archivo += EXT_ARCHIVO;
	} else
		nombre_archivo += EXT_ARCHIVO;
	
	nombreArchivoLex = new char[nombre_archivo.size() + 1];
	strcpy(nombreArchivoLex, nombre_archivo.c_str());
	nombreArchivoLex[nombre_archivo.size()] = '\0';
	//cout << "Lexico.cpp,37: nombreArchivoLex: " << nombreArchivoLex << endl;
	strcpy (this->modo, modo);
	archivoLexico = NULL;
	//no necesito cantidad de registros, pues me manejo por referencias del indice parcial
}

// DESTRUCTOR
Lexico::~Lexico() {
	
	if (archivoLexico != NULL) 
		fclose(archivoLexico);

	if (destroy)
		remove (nombreArchivoLex);
	
	delete [] nombreArchivoLex;
}

void Lexico::abrirArchivo () {
	archivoLexico = fopen(nombreArchivoLex, modo);
}

// devuelve el termino dado un offset
char * Lexico::obtenerTermino(int offset)
{
	fseek(archivoLexico, offset, SEEK_SET);

	char size = 0;

	fread((void *)&size, sizeof(char), 1, archivoLexico);

	char * termino = new char[size + 1];

    fread((void *)termino, size, 1, archivoLexico);
    
    termino[size] = '\0';
    
    
    return termino;
}

//devuelve la long de lo que guardo
void Lexico::escribirTermino(string termino) {
	char longitud = termino.size();
	
	fwrite((void *)&longitud, sizeof(longitud), 1, archivoLexico);
	fwrite((void *)termino.c_str(), termino.size(), 1, archivoLexico);
}

int Lexico::obtenerOffsetActual() {
	return ftell(archivoLexico);
}

void Lexico::resetearCodigoArchivo() {
	Lexico::codigoArchivo = 0;
}

void Lexico::resetearCodigoArchivoNivel1() {
	Lexico::codigoArchivoNivel1 = 0;
}

void Lexico::setDestroy() {
	destroy = true;
}

void Lexico::renombrarArchivoFinal () {
	
	string nombreArchivoFinal;
	
	nombreArchivoFinal = Entorno::Instance().getDataPath();
	nombreArchivoFinal += NOMBRE_ARCHIVO_LEXICO;
	nombreArchivoFinal += EXT_ARCHIVO;
	
	rename (nombreArchivoLex, nombreArchivoFinal.c_str());
	delete [] nombreArchivoLex;
	nombreArchivoLex = new char[nombreArchivoFinal.size() + 1];
	strcpy(nombreArchivoLex, nombreArchivoFinal.c_str());
	nombreArchivoLex[nombreArchivoFinal.size()] = '\0';
}

void Lexico::renombrarArchivoANivel (char * nivel) {

	string nombreArchivoLexico;
	stringstream cod_str;

	
	if (strcmp (nivel, NIVEL_0) == 0) 
		cod_str << ++codigoArchivo;
	else
		cod_str << ++codigoArchivoNivel1;

	nombreArchivoLexico = Entorno::Instance().getDataPath();
	nombreArchivoLexico += NOMBRE_ARCHIVO_LEXICO;
	nombreArchivoLexico += nivel;
	nombreArchivoLexico += cod_str.str();
	nombreArchivoLexico += EXT_ARCHIVO;

	rename (nombreArchivoLex, nombreArchivoLexico.c_str());
	delete [] nombreArchivoLex;
	nombreArchivoLex = new char[nombreArchivoLexico.size() + 1];
	strcpy(nombreArchivoLex, nombreArchivoLexico.c_str());
	nombreArchivoLex[nombreArchivoLexico.size()] = '\0';
}
